package com.marvels.financial.loan.api.impl;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.marvels.financial.loan.dao.McfeCustomerPreviewRepaymentPlanDao;
import com.marvels.financial.loan.dto.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.dto.MarvelsResultDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.exception.MarvelsErrorCode;
import com.marvels.common.utils.CommonProperties;
import com.marvels.common.utils.DateUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.MarvelsUtils;
import com.marvels.financial.consum.FinancialConsumerApproveApi;
import com.marvels.financial.loan.api.FinancialILoanAfterInfoForCommonApi;
import com.marvels.financial.loan.api.IProductInfoApi;
import com.marvels.financial.loan.dao.McfeFundSourceRateDao;

import cn.hutool.core.date.DateUtil;

@Service
public class FinancialLoanAfterInfoForCommonApiImpl implements FinancialILoanAfterInfoForCommonApi {
	@Autowired
	private IProductInfoApi iProductInfoApi;
	@Autowired
	private McfeFundSourceRateDao mcfeFundSourceRateDao;

	@Autowired
	private FinancialConsumerApproveApi consumerApproveApi;
	@Autowired
	private McfeCustomerPreviewRepaymentPlanDao mcfeCustomerPreviewRepaymentPlanDao;

	/**
	 *
	* @Title: createLoanAfterInfo
	* @Description:生成合同划款计划dto类（试算+生成实际还款计划都是调用这个地方）
	* @param loanAfterInfo
	* @return
	* @throws MarvelsBusinessException
	* @author 李瑶
	* @date 2018年10月17日 下午3:44:50
	 */
	@Override
	public McfeCustomerLoanContractDTO createLoanAfterInfo(LoanAfterInfoDTO loanAfterInfo)
			throws MarvelsBusinessException {
		if (loanAfterInfo == null) {
			throw new MarvelsBusinessException("传入参数为空");
		}
		MarvelsLogUtil.getInstance()
				.info("--贷款试算服务-start---loanId===" + loanAfterInfo.getLoanId() + "------amount:"
						+ loanAfterInfo.getAmount() + ";date:" + loanAfterInfo.getDate() + ";productCode:"
						+ loanAfterInfo.getProductCode() + ";tenor:" + loanAfterInfo.getTenor() + ";fundSource:"
						+ loanAfterInfo.getFundSource());
		// 参数校验
		if (loanAfterInfo.getAmount() == null || BigDecimal.ZERO.compareTo(loanAfterInfo.getAmount()) >= 0) {
			throw new MarvelsBusinessException("贷款金额错误,loanId----" + loanAfterInfo.getLoanId());
		}
		if (loanAfterInfo.getTenor() == null || 0 == loanAfterInfo.getTenor()) {
			throw new MarvelsBusinessException("贷款期限错误,loanId----" + loanAfterInfo.getLoanId());
		}
		if (loanAfterInfo.getDate() == null) {
			throw new MarvelsBusinessException("贷款日期为空,loanId----" + loanAfterInfo.getLoanId());
		}
		if (loanAfterInfo.getProductCode() == null) {
			throw new MarvelsBusinessException("产品编号为空,loanId----" + loanAfterInfo.getLoanId());
		}
		McptProduct dto = new McptProduct();
		dto.setProductCode(loanAfterInfo.getProductCode());
		// 查询小类的所有信息
		MarvelsResultDTO rateFeeDTO = iProductInfoApi.queryFeeRateByProductCode(dto);
		if (rateFeeDTO == null) {
			throw new MarvelsBusinessException("查询产品小类相关信息失败");
		}
		//查询资金源费率
		McfeFundSourceRateDTO mcfeFundSourceRateDTO = mcfeFundSourceRateDao.selectFundSourceRateByFundCode(loanAfterInfo.getFundSource()==null?"1":loanAfterInfo.getFundSource(),loanAfterInfo.getProductCode());
		MarvelsLogUtil.getInstance().info("the fundsource rate is ---------"+mcfeFundSourceRateDTO);
		McptProduct mcptProduct = null;// 查询产品小类信息
		McptAmortMethodDTO mcptAmortMethodDTO = null;// 查询产品小类还款方式
		McptConsultingFeeDTO mcptConsultingFeeDTO = null;// 查询产品小类咨询费
		McptManagementFeeDTO mcptManagementFeeDTO = null;// 查询产品小类管理费
		McptMiscFeeDTO mcptMiscFeeDTO = null;// 查询产品小类杂费
		McptPlatformFeeDTO mcptPlatformFeeDTO = null;// 查询产品小类平台费
		McptProductFundRelationDto mcptProductFundRelationDto = null;// 查询产品小类利率
		McptPreTerminationFeeDTO mcptPreTerminationFeeDTO = null;//提前结清费
		McptLateFeeDTO mcptLateFeeDTO = null;//违约金
		McptPenaltyFeeDTO mcptPenaltyFeeDTO = null;//滞纳金
		if (MarvelsErrorCode.SUCCESS.getValue().equals(rateFeeDTO.getCode())) {
			String josnStr = JSON.toJSONString(rateFeeDTO.getData());
			ProductMsgInfoDTO rateFeeMap = JSON.toJavaObject(JSON.parseObject(josnStr), ProductMsgInfoDTO.class);
			mcptProduct = rateFeeMap.getMcptProduct();// 产品小类信息
			mcptAmortMethodDTO = rateFeeMap.getMcptAmortMethodDTO();// 产品小类还款方式
			MarvelsLogUtil.getInstance().info(" this amort method is ----"+mcptAmortMethodDTO);
			mcptConsultingFeeDTO = rateFeeMap.getMcptConsultingFeeDTO();// 产品小类咨询费
			mcptManagementFeeDTO = rateFeeMap.getMcptManagementFeeDTO();// 产品小类管理费
			mcptPlatformFeeDTO = rateFeeMap.getMcptPlatformFeeDTO();// 产品小类平台费
			mcptMiscFeeDTO = rateFeeMap.getMcptMiscFeeDTO();// 产品小类杂费
			mcptPreTerminationFeeDTO = rateFeeMap.getMcptPreTerminationFeeDTO();
			mcptPenaltyFeeDTO = rateFeeMap.getMcptPenaltyFeeDTO();//违约金
			mcptLateFeeDTO = rateFeeMap.getMcptLateFeeDTO();//滞纳金
			List<McptProductFundRelationDto> mcptProductFundRelationDtoList = (List<McptProductFundRelationDto>) rateFeeMap
					.getMcptProductFundRelationDto();
			if (mcptProductFundRelationDtoList != null && mcptProductFundRelationDtoList.size() > 0) {
				mcptProductFundRelationDto = mcptProductFundRelationDtoList.get(0);
			} else {
				mcptProductFundRelationDto = new McptProductFundRelationDto();
			}
			if (mcptProduct == null) {
				throw new MarvelsBusinessException("产品编号:" + loanAfterInfo.getProductCode() + " 对应的产品信息不存在！,loanId----"
						+ loanAfterInfo.getLoanId());
			}
			if (mcptAmortMethodDTO == null) {
				throw new MarvelsBusinessException("产品编号:" + loanAfterInfo.getProductCode() + " 对应的还款方式 "
						+ mcptProduct.getAmortCode() + " 不存在！,loanId----" + loanAfterInfo.getLoanId());
			}
			if (mcptConsultingFeeDTO == null) {
				mcptConsultingFeeDTO = new McptConsultingFeeDTO();
			}
			if (mcptManagementFeeDTO == null) {
				mcptManagementFeeDTO = new McptManagementFeeDTO();
			}
			if (mcptMiscFeeDTO == null) {
				mcptMiscFeeDTO = new McptMiscFeeDTO();
			}
			if (mcptPlatformFeeDTO == null) {
				mcptPlatformFeeDTO = new McptPlatformFeeDTO();
			}
			if (mcptPreTerminationFeeDTO == null) {
				mcptPreTerminationFeeDTO = new McptPreTerminationFeeDTO();
			}
			if (mcptPenaltyFeeDTO == null) {
				mcptPenaltyFeeDTO = new McptPenaltyFeeDTO();
			}
			if (mcptLateFeeDTO == null) {
				mcptLateFeeDTO = new McptLateFeeDTO();
			}
		} else {
//			MarvelsLogUtil.getInstance().info(rateFeeDTO.getMessage());
			throw new MarvelsBusinessException(rateFeeDTO.getData() + ",loanId----" + loanAfterInfo.getLoanId());
		}

		MarvelsLogUtil.getInstance().info(mcptProduct + "");
		McfeCustomerLoanInfoDTO CustomerLoanInfo = new McfeCustomerLoanInfoDTO();
		// 生成贷款合同
		MarvelsLogUtil.getInstance().info("start init contract ,the loan_id is :====" + loanAfterInfo.getLoanId());
		McfeCustomerLoanContractDTO contract = initContractInfo(loanAfterInfo,
				mcptProductFundRelationDto, mcptProduct,mcptLateFeeDTO,mcptPenaltyFeeDTO);
		MarvelsLogUtil.getInstance().info("start init plan list ,the loan_id is :====" + loanAfterInfo.getLoanId());


//		//原版生成还款计划
		List<McfeCustomerRepaymentPlanDTO> planList = producePaymentPlan(mcptProduct, mcptProductFundRelationDto,
				mcptPlatformFeeDTO, mcptMiscFeeDTO, mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptAmortMethodDTO,
				loanAfterInfo, contract,mcfeFundSourceRateDTO);


		// 重写还款计划
//		List<McfeCustomerRepaymentPlanDTO> planList = new ArrayList<>();

		if (planList == null || planList.size() == 0) {
			throw new MarvelsBusinessException("生成还款计划失败");
		}
		// 遍历还款计划，更新合同
		iteratorPlanList(planList, contract);
		// 客户贷款信息表
		updateAccount2(contract, CustomerLoanInfo);
		contract.setPlanList(planList);
		contract.setCustomerLoanInfo(CustomerLoanInfo);
		contract.setMcptConsultingFeeDTO(mcptConsultingFeeDTO);
		FeeRateDTO feeRateDTO = new FeeRateDTO();
		feeRateDTO.setInterestRate(mcptProductFundRelationDto.getRate());
		feeRateDTO.setConsultingFeeRate(mcptConsultingFeeDTO.getPercentage());
		feeRateDTO.setManagementFeeRate(mcptManagementFeeDTO.getPercentage());
		feeRateDTO.setPenaltyFeeRate(mcptManagementFeeDTO.getPercentage());
		feeRateDTO.setPreTerminateFeeRate(mcptPreTerminationFeeDTO.getPercentage());
		feeRateDTO.setMiscFeeRate(mcptMiscFeeDTO.getPercentage());
		feeRateDTO.setPlatformFeeRate(mcptPlatformFeeDTO.getPercentage());
		if(mcfeFundSourceRateDTO!=null){
			feeRateDTO.setFundInterestRate(mcfeFundSourceRateDTO.getInterestRate());
		}else{
			feeRateDTO.setFundInterestRate(BigDecimal.valueOf(0));

		}
		loanAfterInfo.setFeeRateDTO(feeRateDTO);
		contract.setMcptPenaltyFeeDTO(mcptPenaltyFeeDTO);//违约金
		contract.setMcptLateFeeDTO(mcptLateFeeDTO);//滞纳金
		return contract;
	}

	/**
	 * 更新借款账户信息
	 *
	 * @param contractAccount2Info
	 * @param account2Info
	 * @return
	 */
	public McfeCustomerLoanInfoDTO updateAccount2(McfeCustomerLoanContractDTO contractAccount2Info,
			McfeCustomerLoanInfoDTO account2Info) {
		account2Info.setCustCardNo(contractAccount2Info.getCustCardNo());
		account2Info.setCustName(contractAccount2Info.getCustName());
		account2Info.setLoanId(contractAccount2Info.getLoanId());
		account2Info.setStatus(MarvelsConstant.PAYMENT_PLAN_STATUS_NORMAL);
		// 未还本金
		account2Info.setPrincipalOs(account2Info.getPrincipalOs().add(contractAccount2Info.getPrincipalOs()));
		// 未还利息
		account2Info.setInterestOs(account2Info.getInterestOs().add(contractAccount2Info.getInterestOs()));
		// 未还费用1
		account2Info
				.setConsultingFeeOs(account2Info.getConsultingFeeOs().add(contractAccount2Info.getConsultingFeeOs()));
		// 未还费用2
		account2Info.setManagementFeeOs(account2Info.getManagementFee().add(contractAccount2Info.getManagementFeeOs()));
		// 未还杂费
		account2Info.setMiscFeeOs(account2Info.getMiscFeeOs().add(contractAccount2Info.getMiscFeeOs()));
		// 未还平台费用
		account2Info.setPlatformFeeOs(account2Info.getPlatformFeeOs().add(contractAccount2Info.getPlatformFeeOs()));
		// 未还风险金
		// account2Info.setRiskFeeOs(account2Info.getRiskFeeOs().add(contractAccount2Info.getRiskFeeOs()));
		// 最后更新时间
		account2Info.setUpdatedDate((new Timestamp(new Date().getTime())));
		//更新已收咨询费信息
		account2Info.setConsultingFee(account2Info.getConsultingFee().add(contractAccount2Info.getConsultingFee()));
		// 最后更新人员
		account2Info.setUpdatedBy((MarvelsConstant.SYSTEM_USER));
		account2Info.setCreatedBy(MarvelsConstant.SYSTEM_USER);
		account2Info.setCreatedDate(new Date());
		return account2Info;
	}

	/**
	 * 遍历还款计划，初始化合同
	 *
	 * @param list
	 * @param contract
	 * @return
	 */
	private McfeCustomerLoanContractDTO iteratorPlanList(List<McfeCustomerRepaymentPlanDTO> list,
			McfeCustomerLoanContractDTO contract) {

		// 未还本金
		BigDecimal principalOs = BigDecimal.ZERO;
		// 未还利息
		BigDecimal interestOs = BigDecimal.ZERO;
		// 咨询费
		BigDecimal consultingFeeOs = BigDecimal.ZERO;
		// 已还咨询费
		BigDecimal consultingFee = BigDecimal.ZERO;
		// 管理费
		BigDecimal managementFeeOs = BigDecimal.ZERO;
		// 未还罚费
		BigDecimal penaltyFeeOs = BigDecimal.ZERO;
		// 未还杂费
		BigDecimal miscFeeOs = BigDecimal.ZERO;
		// 未还平台费
		BigDecimal platformFeeOs = BigDecimal.ZERO;
		//资金源未还本金
		BigDecimal fundPrincipalOs = BigDecimal.ZERO;
		//资金源未还利息
		BigDecimal fundInterestOs = BigDecimal.ZERO;
		// 更新合同期数：因利随本清只有一期
		contract.setTenor(list.size());
		Iterator<McfeCustomerRepaymentPlanDTO> iterator = list.iterator();
		while (iterator.hasNext()) {
			McfeCustomerRepaymentPlanDTO paymentInfo = (McfeCustomerRepaymentPlanDTO) iterator.next();
			// 更新合同首期还款信息
			if (paymentInfo.getTenor() == 1) {
				//设置已还咨询费信息
				contract.setConsultingFee(paymentInfo.getConsultingFeeAct());
				// 首期还款金额
				contract.setFirstPaymentAmount(paymentInfo.getPrincipal().add(paymentInfo.getManagementFee())
						.add(paymentInfo.getInterest()).add(paymentInfo.getConsultingFee()));
				// 首次还款日期
				contract.setFirstPaymentDate(paymentInfo.getPaymentDateLate());
			}
			// 更新合同末期还款信息
			if (paymentInfo.getTenor() == contract.getTenor()) {
				// 最后还款金额
				contract.setLastPaymentAmount(paymentInfo.getPrincipal().add(paymentInfo.getManagementFee())
						.add(paymentInfo.getInterest()).add(paymentInfo.getConsultingFee()));
				// 最后还款日期
				contract.setLastPaymentDate(paymentInfo.getPaymentDateLate());
			}
			principalOs = principalOs.add(paymentInfo.getPrincipal());
			interestOs = interestOs.add(paymentInfo.getInterest());
			consultingFee = consultingFee.add(paymentInfo.getConsultingFeeAct());
			//已还咨询费=还款计划应还咨询费-已还咨询费
			consultingFeeOs = consultingFeeOs.add(paymentInfo.getConsultingFee().subtract(paymentInfo.getConsultingFeeAct()));
			managementFeeOs = managementFeeOs.add(paymentInfo.getManagementFee());
			penaltyFeeOs = penaltyFeeOs.add(paymentInfo.getPenaltyFee());
			miscFeeOs = miscFeeOs.add(paymentInfo.getMiscFee());
			platformFeeOs = platformFeeOs.add(paymentInfo.getPlatformFee());
			fundPrincipalOs = fundPrincipalOs.add(paymentInfo.getFundPrincipal());
			fundInterestOs = fundInterestOs.add(paymentInfo.getFundInterest());
		}

		// 未还本金
		contract.setPrincipalOs(principalOs);
		//已还咨询费
		contract.setConsultingFee(consultingFee);
		// 未还利息
		contract.setInterestOs(interestOs);
		// 未还咨询费
		contract.setConsultingFeeOs(consultingFeeOs);
		// 未还管理费
		contract.setManagementFeeOs(managementFeeOs);
		// 未还罚费
		contract.setPenaltyFeeOs(penaltyFeeOs);
		// 未还杂费
		contract.setMiscFeeOs(miscFeeOs);
		// 未还平台费
		contract.setPlatformFeeOs(platformFeeOs);
		//未还资金源本金
		contract.setFundPrincipalOs(fundPrincipalOs);
		//未还资金源利息
		contract.setFundInterestOs(fundInterestOs);
		// // 未还风险金
		// contract.setRiskFeeOs(riskFeeOs);
		// 合同结束时间为最后还款日期
		contract.setEndDate(contract.getLastPaymentDate());
		return contract;
	}

	/**
	 * 生成合同信息
	 *
	 * @author 娄凯琦
	 * @date 2018年5月9日
	 * @param amount贷款金额
	 * @param tenor期数
	 * @param date日期
	 * @param productCode产品小类
	 * @param fundCode资金源code
	 * @param fundName资金源名称
	 * @return
	 */
	@Override
	public McfeCustomerLoanContractDTO initContractInfo(LoanAfterInfoDTO loanAfterInfo,McptProductFundRelationDto mcptProductFundRelationDto,McptProduct mcptProduct,McptLateFeeDTO mcptLateFeeDTO,McptPenaltyFeeDTO mcptPenaltyFeeDTO) {
		McfeCustomerLoanContractDTO contractTmp = new McfeCustomerLoanContractDTO();
		// 客户名称
		contractTmp.setCustName(loanAfterInfo.getCustName());
		// 客户证件号码
		contractTmp.setCustCardNo(loanAfterInfo.getCustCardNo());
		// 合同模板编号--暂未使用，默认为0
		contractTmp.setContractNo("");
		// 状态正常
		contractTmp.setStatus(MarvelsConstant.STATUS_A0);
		// 金额
		contractTmp.setAmount(loanAfterInfo.getAmount());
		// 还款方式id
		// contractTmp.setAmortMethod(product.getAmortMethod());
		// 期数
		contractTmp.setTenor(loanAfterInfo.getTenor());
		// 当前期数
		contractTmp.setCurrTenor(1);
		// 起始日期
		contractTmp.setStartDate(loanAfterInfo.getDate());
		contractTmp.setProductName(mcptProduct.getProductName());
		// 产品大类
		contractTmp.setProductType(mcptProduct.getProductType());
		// 产品大类名称
		contractTmp.setProductTypeName(mcptProduct.getProductTypeName());
		// 渠道
		contractTmp.setChannelCode(loanAfterInfo.getChannelCode());
		// 渠道名称
		contractTmp.setChannelName(loanAfterInfo.getChannelName());
		// 创建人
		contractTmp.setCreatedBy(MarvelsConstant.SYSTEM_USER);
		// 创建时间
		contractTmp.setCreatedDate(new Date());
		contractTmp.setMobile(loanAfterInfo.getMobile());
		contractTmp.setPaymentAcctName(loanAfterInfo.getPaymentAcctName());
		contractTmp.setPaymentAcctNo(loanAfterInfo.getPaymentAcctNo());
		contractTmp.setPaymentBankBranch(loanAfterInfo.getPaymentBankBranch());
		contractTmp.setPaymentBankHead(loanAfterInfo.getPaymentBankHead());
		contractTmp.setPaymentBankName(loanAfterInfo.getPaymentBankName());
		// 最后更新时间
		contractTmp.setUpdatedDate(new Date());
		// 最后更新人员
		contractTmp.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
		// 逾期天数
		contractTmp.setDelqDays(0);
		McamLoanApplyInfoDTO infoDTO=new McamLoanApplyInfoDTO();
		infoDTO.setLoanId(loanAfterInfo.getLoanId());
		infoDTO=consumerApproveApi.selectLoanApplyInfo(infoDTO);
		// 产品编号
		contractTmp.setProductCode(infoDTO.getProductCode());
		// 渠道受理号
		contractTmp.setLoanId(loanAfterInfo.getLoanId());
		// 资金源id
		contractTmp.setFundCode(infoDTO.getFundCode());
		// 资金源名称
		contractTmp.setFundName(infoDTO.getFundName());

		contractTmp.setPenaltyFeeId(mcptPenaltyFeeDTO.getPenaltyFeeId());
		contractTmp.setPenaltyFeeType(mcptPenaltyFeeDTO.getFeeType());
		contractTmp.setPenaltyMinFee(mcptPenaltyFeeDTO.getMinFee());
		contractTmp.setPenaltyMaxFee(mcptPenaltyFeeDTO.getMaxFee());
		contractTmp.setPenaltyPercentage(mcptPenaltyFeeDTO.getPercentage());
		contractTmp.setLateFeeId(mcptLateFeeDTO.getLateFeeId());
		contractTmp.setPatternType(loanAfterInfo.getPatternType());
		contractTmp.setLateFeeType(mcptLateFeeDTO.getFeeType());
		contractTmp.setLateMinFee(mcptLateFeeDTO.getMinFee());
		contractTmp.setLateMaxFee(mcptLateFeeDTO.getMaxFee());
		contractTmp.setLatePercentage(mcptLateFeeDTO.getPercentage());
		contractTmp.setLateBaseAmtType(mcptLateFeeDTO.getBaseAmtType());
		return contractTmp;
	}


	/**生成还款计划
	 * @author 娄凯琦
	 * @date 2018年5月16日
	 * @param mcptProduct产品小类
	 * @param mcptProductFundRelationDto产品映射资金源
	 * @param mcptPlatformFeeDTO平台费
	 * @param mcptMiscFeeDTO杂费
	 * @param mcptManagementFeeDTO管理费
	 * @param mcptConsultingFeeDTO咨询费
	 * @param mcptAmortMethodDTO还款方式
	 * @param loanAfterInfo贷后信息dto
	 * @param contract合同信息
	 * @param mcfeFundSourceRateDTO资金源费率
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> producePaymentPlan(McptProduct mcptProduct,
			McptProductFundRelationDto mcptProductFundRelationDto, McptPlatformFeeDTO mcptPlatformFeeDTO,
			McptMiscFeeDTO mcptMiscFeeDTO, McptManagementFeeDTO mcptManagementFeeDTO,
			McptConsultingFeeDTO mcptConsultingFeeDTO, McptAmortMethodDTO mcptAmortMethodDTO,
			LoanAfterInfoDTO loanAfterInfo, McfeCustomerLoanContractDTO contract,
			McfeFundSourceRateDTO mcfeFundSourceRateDTO) {
		List<McfeCustomerRepaymentPlanDTO> planList = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		int roundFlag = 0;

		if (mcptAmortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_HALF_UP ) {
			roundFlag = BigDecimal.ROUND_HALF_UP;
		} else if (mcptAmortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_UP) {
			roundFlag = BigDecimal.ROUND_UP;
		} else if (mcptAmortMethodDTO.getRoundUp()==MarvelsConstant.ROUND_DOWN) {
			roundFlag = BigDecimal.ROUND_DOWN;
		}

		// 获取还款方式
		String amortMethod = mcptAmortMethodDTO.getAmortCode();
		MarvelsLogUtil.getInstance().info(">>>>>>>loanId:"+contract.getLoanId()+",amortMethod="+amortMethod);
		BigDecimal yearFundRate = BigDecimal.ZERO;
		if (null != mcfeFundSourceRateDTO) {
			yearFundRate = mcfeFundSourceRateDTO.getInterestRate();
		}
		if(yearFundRate == null){
			yearFundRate = BigDecimal.ZERO;
		}

		// 根据还款方式调用不同方法
		// 按季结息，到期还本付息
		if (MarvelsConstant.AMORT_QUATER_INT_PAY_OFF_END.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			planList = computeQIPayEnd(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), roundFlag, mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		// 按月结息，到期还本付息
		else if (MarvelsConstant.AMORT_MONTH_INT_PAY_OFF_END.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			planList = computeEIPayEnd(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), roundFlag, mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		// 等额本金
		else if (MarvelsConstant.AMORT_EQUAL_P.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			planList = computeEP(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), roundFlag, mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		// 等额本息
		else if (MarvelsConstant.AMORT_EQUAL_PI.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			MarvelsLogUtil.getInstance().info(">>>>>>>loanId:"+contract.getLoanId()+",初始化还款计划开始");
			planList = computeEPI(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), roundFlag, mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			MarvelsLogUtil.getInstance().info(">>>>>>>loanId:"+contract.getLoanId()+",更新费用等相关信息开始");
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		// 分期付款
		else if (MarvelsConstant.AMORT_INSTALLMENT.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			planList = installment(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), roundFlag, mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		// 利随本清
		else if (MarvelsConstant.AMORT_PAY_OFF_END.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			planList = paymentEndPI(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), mcptProduct.getCycle(), roundFlag,
					mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		// 随借随还
		else if (MarvelsConstant.AMORT_ANY.equalsIgnoreCase(amortMethod)) {
			// 初始化还款计划
			planList = paymentEndAny(contract, contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), mcptProduct, roundFlag,
					mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}
		else if (MarvelsConstant.AMORT_INIT.equalsIgnoreCase(amortMethod))
		{

			planList = paymentInitAny(loanAfterInfo,contract,contract.getAmount(), contract.getStartDate(), contract.getTenor(),
					mcptProductFundRelationDto.getRate(), roundFlag, mcptAmortMethodDTO.getRoundDigit(), yearFundRate);
			// 更新费用等相关信息
			planList = updateFeeForPlan(contract.getAmount(), planList, mcptPlatformFeeDTO, mcptMiscFeeDTO,
					mcptManagementFeeDTO, mcptConsultingFeeDTO, mcptProduct, mcptAmortMethodDTO.getRoundDigit(),
					roundFlag);
		}else{
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>>>loanId:"+contract.getLoanId()+",还款方式错误");
		}
		return planList;
	}
	/**
	 * @param: contract 合同信息
	 * @param: amount 贷款金额
	 * @param: date 贷款起始日期
	 * @param: tenor 期数
	 * @param: yearRate 年利率
	 * @param: roundUpFlag 进位方式
	 * @param: roundDigits 精确度
	 * @param: yearFundRate
	 * @return: java.util.List<com.marvels.financial.loan.dto.McfeCustomerRepaymentPlanDTO>
	 * @author 11271
	 * @date: 2022/3/29 17:22
	 */
	private List<McfeCustomerRepaymentPlanDTO> paymentInitAny(LoanAfterInfoDTO loanAfterInfo,McfeCustomerLoanContractDTO contract, BigDecimal amount, Date date, int tenor, BigDecimal yearRate, int roundUpFlag, int roundDigits, BigDecimal yearFundRate) {
		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<>();
		List<McfeCustomerPreviewRepaymentPlanDTO> mcfeCustomerPreviewRepaymentPlanDTOList = mcfeCustomerPreviewRepaymentPlanDao.selectPreviewRepaymentList(loanAfterInfo.getLoanId());
		for(McfeCustomerPreviewRepaymentPlanDTO item : mcfeCustomerPreviewRepaymentPlanDTOList){
			McfeCustomerRepaymentPlanDTO plan = initPlan(contract, item.getPrincipal(), item.getInterest(), item.getPaymentDate(),  Integer.valueOf(item.getTenor()),
					BigDecimal.ZERO);
			plan.setPaymentDate(item.getPaymentDate());
			plan.setPaymentDateLate(item.getPaymentDate());
			list.add(plan);
		}
		return list;
	}

	/**
	 * 按月结息，到期还本付息
	 *
	 * @param contract
	 *            合同信息
	 * @param amount
	 *            贷款金额
	 * @param date
	 *            贷款起始日期
	 * @param tenor
	 *            期数
	 * @param yearRate
	 *            年利率
	 * @param roundUpFlag
	 *            进位方式
	 * @param roundDigits
	 *            精确度
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> computeEIPayEnd(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, int tenor, BigDecimal yearRate, int roundUpFlag, int roundDigits, BigDecimal yearFundRate) {
		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 月还款本金
		BigDecimal monthlyPrincipal = BigDecimal.ZERO;
		// 月还款利息
		BigDecimal monthlyInterest = BigDecimal.ZERO;
		BigDecimal monthlyFundInterest = BigDecimal.ZERO;
		// 月利率
		BigDecimal monthlyRate = yearRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		BigDecimal monthlyFundRate = yearFundRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		for (int i = 1; i <= tenor; i++) {
			monthlyInterest = amount.multiply(monthlyRate).setScale(roundDigits, roundUpFlag);
			monthlyFundInterest = amount.multiply(monthlyFundRate).setScale(roundDigits, roundUpFlag);
			if (i == tenor) {
				monthlyPrincipal = amount;
			}
			// 初始化还款计划数据
			McfeCustomerRepaymentPlanDTO plan = initPlan(contract, monthlyPrincipal, monthlyInterest, date, i,
					monthlyFundInterest);
			list.add(plan);
		}
		return list;
	}

	/**
	 * 按季结息，到期还本付息
	 *
	 * @param contract
	 *            合同信息
	 * @param amount
	 *            贷款金额
	 * @param date
	 *            贷款起始日期
	 * @param tenor
	 *            期数
	 * @param yearRate
	 *            年利率
	 * @param roundUpFlag
	 *            进位方式
	 * @param roundDigits
	 *            精确度
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> computeQIPayEnd(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, Integer tenor, BigDecimal yearRate, int roundUpFlag, Integer roundDigits,
			BigDecimal yearFundRate) {
		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 季度还款本金
		BigDecimal quartPrincipal = BigDecimal.ZERO;
		// 季度还款利息
		BigDecimal quartInterest = BigDecimal.ZERO;
		BigDecimal quartFundInterest = BigDecimal.ZERO;
		// 月利率
		BigDecimal monthlyRate = yearRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		// 资金源月利率
		BigDecimal monthlyFundRate = yearFundRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		// 当前期数
		for (int i = 1; i <= tenor; i++) {
			if (i % 3 == 0) {
				// 计算当前期数
				int cTneor = i / 3;
				// 计算季度利息
				quartInterest = amount.multiply(monthlyRate).multiply(BigDecimal.valueOf(3)).setScale(roundDigits,
						roundUpFlag);
				quartFundInterest = amount.multiply(monthlyFundRate).multiply(BigDecimal.valueOf(3))
						.setScale(roundDigits, roundUpFlag);
				if (i == tenor) {
					quartPrincipal = amount;
				}
				// 初始化还款计划数据
				McfeCustomerRepaymentPlanDTO plan = initPlan(contract, quartPrincipal, quartInterest, date, cTneor,
						quartFundInterest);
				list.add(plan);
			} else {
				if (i == tenor) {
					int month = i % 3;
					// 计算当前期数
					int cTneor = i / 3 + 1;
					quartInterest = amount.multiply(monthlyRate).multiply(BigDecimal.valueOf(month))
							.setScale(roundDigits, roundUpFlag);
					quartFundInterest = amount.multiply(monthlyFundRate).multiply(BigDecimal.valueOf(month))
							.setScale(roundDigits, roundUpFlag);
					quartPrincipal = amount;
					// 初始化还款计划数据
					McfeCustomerRepaymentPlanDTO plan = initPlan(contract, quartPrincipal, quartInterest, date, cTneor,
							quartFundInterest);
					list.add(plan);
				}
			}
		}
		return list;
	}

	/**
	 * 等额本金
	 *
	 * @param contract
	 *            合同信息
	 * @param amount
	 *            贷款金额
	 * @param date
	 *            贷款起始日期
	 * @param tenor
	 *            期数
	 * @param yearRate
	 *            年利率
	 * @param roundUpFlag
	 *            进位方式
	 * @param roundDigits
	 *            精确度
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> computeEP(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, int tenor, BigDecimal yearRate, int roundUpFlag, int roundDigits, BigDecimal yearFundRate) {
		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 月还款本金
		BigDecimal monthlyPrincipal = BigDecimal.ZERO;
		// 月还款利息
		BigDecimal monthlyInterest = BigDecimal.ZERO;
		BigDecimal monthlyFundInterest = BigDecimal.ZERO;
		// 月利率
		BigDecimal monthlyRate = yearRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		BigDecimal monthlyFundRate = yearFundRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);

		monthlyPrincipal = amount
				.divide(BigDecimal.valueOf(tenor), MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP)
				.setScale(roundDigits, roundUpFlag);
		for (int i = 1; i <= tenor; i++) {
			monthlyInterest = amount.multiply(monthlyRate).setScale(roundDigits, roundUpFlag);
			monthlyFundInterest = amount.multiply(monthlyFundRate).setScale(roundDigits, roundUpFlag);
			if (i != tenor) {
				amount = amount.subtract(monthlyPrincipal);
			} else {
				monthlyPrincipal = amount;
			}
			// 初始化还款计划数据
			McfeCustomerRepaymentPlanDTO plan = initPlan(contract, monthlyPrincipal, monthlyInterest, date, i,
					monthlyFundInterest);
			list.add(plan);
		}
		return list;
	}

	/**
	 * 等额本息
	 *
	 * @param contract
	 *            合同信息
	 * @param amount
	 *            贷款金额
	 * @param date
	 *            贷款起始日期
	 * @param tenor
	 *            期数
	 * @param yearRate
	 *            年利率
	 * @param roundUpFlag
	 *            进位方式
	 * @param roundDigits
	 *            精确度
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> computeEPI(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, int tenor, BigDecimal yearRate, int roundUpFlag, int roundDigits, BigDecimal yearFundRate) {

		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 月还款金额
		BigDecimal monthlyPayment = BigDecimal.ZERO;
		// 月还款本金
		BigDecimal monthlyPrincipal = BigDecimal.ZERO;
		// 月还款利息
		BigDecimal monthlyInterest = BigDecimal.ZERO;
		BigDecimal monthlyFundInterest = BigDecimal.ZERO;
		// 日利率
		BigDecimal dayRate = BigDecimal.ZERO;

		MarvelsLogUtil.getInstance()
				.info("yearRate:"+yearRate);
		// 月利率
		BigDecimal monthlyRate = yearRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		BigDecimal monthlyFundRate = yearFundRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);


		// 还款日期
		Date paymentDate = computeDate(date, tenor);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
//		int days = new GregorianCalendar().isLeapYear(year) ? 366 : 365;
		int days = 365;
		dayRate = yearRate.divide(BigDecimal.valueOf(days), MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);

		// 计算月还款总额
		MarvelsLogUtil.getInstance()
				.info(monthlyRate + "---;" + yearRate + "------;" + Math.pow((1 + monthlyRate.doubleValue()), tenor));
		monthlyPayment = amount.multiply(monthlyRate)
				.multiply(BigDecimal.valueOf(Math.pow((1 + monthlyRate.doubleValue()), tenor)))
				.divide(BigDecimal.valueOf(Math.pow((1 + monthlyRate.doubleValue()), tenor) - 1),
						MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP)
				.setScale(roundDigits, roundUpFlag);
		for (int i = 1; i <= tenor; i++) {
//			monthlyInterest = amount.multiply(monthlyRate).setScale(2, roundUpFlag);
			monthlyInterest = amount.multiply(dayRate).multiply(BigDecimal.valueOf(DateUtils.diffTowDate(date,paymentDate)+1)).setScale(2, roundUpFlag);
//			monthlyFundInterest = amount.multiply(monthlyFundRate).setScale(2, roundUpFlag);
//			monthlyFundInterest = amount.multiply(dayRate).multiply(BigDecimal.valueOf(DateUtils.diffTowDate(paymentDate,date))).setScale(2, roundUpFlag);
			if (i != tenor) {
				monthlyPrincipal = monthlyPayment.subtract(monthlyInterest).setScale(2, roundUpFlag);
				amount = amount.subtract(monthlyPrincipal).setScale(2, roundUpFlag);
			} else {
				monthlyPrincipal = amount;
			}

			// 初始化还款计划数据
			McfeCustomerRepaymentPlanDTO plan = initPlan(contract, monthlyPrincipal, monthlyInterest, date, i,
					monthlyFundInterest);
			list.add(plan);
		}
		return list;
	}

	/**
	 * 分期付款
	 *
	 * @param contract
	 *            合同信息
	 * @param amount
	 *            贷款金额
	 * @param date
	 *            贷款起始日期
	 * @param tenor
	 *            期数
	 * @param yearRate
	 *            年利率
	 * @param roundUpFlag
	 *            进位方式
	 * @param roundDigits
	 *            精确度
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> installment(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, int tenor, BigDecimal yearRate, int roundUpFlag, int roundDigits, BigDecimal yearFundRate) {
		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 月还款本金
		BigDecimal monthlyPrincipal = BigDecimal.ZERO;
		// 月还款利息
		BigDecimal monthlyInterest = BigDecimal.ZERO;
		BigDecimal monthlyFundInterest = BigDecimal.ZERO;
		// 月利率
		BigDecimal monthlyRate = yearRate.multiply(BigDecimal.valueOf(1l + tenor)).divide(BigDecimal.valueOf(24l * tenor),
				MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
		BigDecimal monthlyFundRate = yearFundRate.multiply(BigDecimal.valueOf(1l + tenor))
				.divide(BigDecimal.valueOf(24l * tenor), MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
		// 计算每月本金
		monthlyPrincipal = amount
				.divide(BigDecimal.valueOf(tenor), MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP)
				.setScale(roundDigits, roundUpFlag);
		BigDecimal fixedAmount = amount;
		for (int i = 1; i <= tenor; i++) {
			monthlyInterest = fixedAmount.multiply(monthlyRate).setScale(roundDigits, roundUpFlag);
			monthlyFundInterest = fixedAmount.multiply(monthlyFundRate).setScale(roundDigits, roundUpFlag);
			if (i != tenor) {
				amount = amount.subtract(monthlyPrincipal);
			} else {
				monthlyPrincipal = amount;
			}
			// 初始化还款计划数据
			McfeCustomerRepaymentPlanDTO plan = initPlan(contract, monthlyPrincipal, monthlyInterest, date, i,
					monthlyFundInterest);
			list.add(plan);
		}
		return list;
	}

	/**
	 * 利随本清
	 *
	 * @author 娄凯琦
	 * @date 2018年5月10日
	 * @param contract
	 * @param amount
	 * @param date
	 * @param tenor
	 * @param yearRate
	 * @param yearBase
	 * @param cycle
	 * @param roundUpFlag
	 * @param roundDigits
	 * @param yearFundRate
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> paymentEndPI(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, int tenor, BigDecimal yearRate, String cycle, int roundUpFlag, int roundDigits,
			BigDecimal yearFundRate) {

		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 还款本金
		BigDecimal principal = amount;
		// 还款利息
		BigDecimal interest = BigDecimal.ZERO;
		BigDecimal fundInterest = BigDecimal.ZERO;

		// 月利率
		BigDecimal monthlyRate = yearRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		BigDecimal monthlyFundRate = yearFundRate.divide(BigDecimal.valueOf(12), MarvelsConstant.BIGDECIMAL_SCALE,
				BigDecimal.ROUND_HALF_UP);
		// 日利率
		BigDecimal dayRate = BigDecimal.ZERO;
//		Date startDate = DateUtils.add(contract.getStartDate(),Calendar.DAY_OF_MONTH, -7);
		Date startDate = contract.getStartDate();
		// 还款日期
		Date paymentDate = computeDate(startDate, tenor);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
		Integer year = Integer.parseInt(sdf.format(new Date()));
		int days = new GregorianCalendar().isLeapYear(year) ? 366 : 365;
		dayRate = yearRate.divide(BigDecimal.valueOf(days), MarvelsConstant.BIGDECIMAL_SCALE, BigDecimal.ROUND_HALF_UP);
		// 计算还款利息
		// 按天计算
//		if (cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_DAYS)) {
//			interest = amount.multiply(dayRate).multiply(BigDecimal.valueOf(tenor)).setScale(roundDigits, roundUpFlag);
//			paymentDate = computeDateForDay(startDate, tenor);
//		}
		// 	特殊处理
		if (cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_DAYS)) {
			interest = amount.multiply(dayRate).multiply(BigDecimal.valueOf(DateUtils.diffTowDate(startDate,paymentDate))).setScale(roundDigits, roundUpFlag);
			paymentDate = computeDate(startDate, tenor);
			fundInterest = amount.multiply(dayRate).multiply(BigDecimal.valueOf(DateUtils.diffTowDate(startDate,paymentDate))).setScale(roundDigits, roundUpFlag);
		}
		// 按月计算
		else if (cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_MONTH)) {
			interest = amount.multiply(monthlyRate).multiply(BigDecimal.valueOf(tenor)).setScale(roundDigits,
					roundUpFlag);
			fundInterest = amount.multiply(monthlyFundRate).multiply(BigDecimal.valueOf(tenor)).setScale(roundDigits,
					roundUpFlag);
		}
		McfeCustomerRepaymentPlanDTO plan = initPlan(contract, principal, interest, date, tenor, fundInterest);
		MarvelsLogUtil.getInstance().info("dayRate:"+dayRate);
		MarvelsLogUtil.getInstance().info("天数："+DateUtils.diffTowDate(startDate,paymentDate));
		MarvelsLogUtil.getInstance().info("interest:"+interest);

		// 利随本清只有一期
		plan.setTenor(1);
		plan.setPaymentDate(paymentDate);
		plan.setPaymentDateLate(paymentDate);
		MarvelsLogUtil.getInstance().info("plan"+plan.toString());
		list.add(plan);
		return list;
	}

	/**
	 * 随借随还
	 *
	 * @author 娄凯琦
	 * @date 2018年5月10日
	 * @param contract
	 * @param amount
	 * @param date
	 * @param tenor
	 * @param yearRate
	 * @param yearBase
	 * @param mcptProduct
	 * @param roundUpFlag
	 * @param roundDigits
	 * @param yearFundRate
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> paymentEndAny(McfeCustomerLoanContractDTO contract, BigDecimal amount,
			Date date, int tenor, BigDecimal yearRate, McptProduct mcptProduct, int roundUpFlag, int roundDigits,
			BigDecimal yearFundRate) {

		List<McfeCustomerRepaymentPlanDTO> list = new ArrayList<McfeCustomerRepaymentPlanDTO>();
		// 还款本金
		BigDecimal principal = amount;
		// 还款利息
		BigDecimal interest = BigDecimal.ZERO;
		BigDecimal fundInterest = BigDecimal.ZERO;
		// 还款日期
		Date paymentDate = computeDate(contract.getStartDate(), tenor);
		String cycle = mcptProduct.getCycle();
		String cycleTenor = mcptProduct.getTenor()+"";
		int cycleTenorInt = 0;
	    if(StringUtils.isNotEmpty(cycleTenor)){
	    	cycleTenorInt = Integer.valueOf(cycleTenor);
	    }

	    // 依据配置判断还款周期,为Y是不算放款当天
	    if(StringUtils.equalsIgnoreCase("Y", CommonProperties.getNewRepaymentFlag())) {
			if (cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_DAYS)) {
				paymentDate = computeDateForDay(contract.getStartDate(), cycleTenorInt);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_ONE_WEEK)){
				paymentDate = computeDateForDay(contract.getStartDate(), 7*cycleTenorInt);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_TWO_WEEK)){
				paymentDate = computeDateForDay(contract.getStartDate(), 14*cycleTenorInt);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_MONTH)){
				paymentDate = computeDate(contract.getStartDate(), cycleTenorInt);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_SEASON)){
				paymentDate = computeDate(contract.getStartDate(), cycleTenorInt*3);
			}
	    }else {
			// 按天计算
			if (cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_DAYS)) {
				paymentDate = computeDateForDay(contract.getStartDate(), cycleTenorInt-7);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_ONE_WEEK)){
				paymentDate = computeDateForDay(contract.getStartDate(), 7*cycleTenorInt-7);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_TWO_WEEK)){
				paymentDate = computeDateForDay(contract.getStartDate(), 14*cycleTenorInt-7);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_MONTH)){
				Date startDate = DateUtils.add(contract.getStartDate(),Calendar.DAY_OF_MONTH, -7);
				paymentDate = computeDate(startDate, cycleTenorInt);
			}else if(cycle.equalsIgnoreCase(MarvelsConstant.TENOR_TYPE_SEASON)){
				Date startDate = DateUtils.add(contract.getStartDate(),Calendar.DAY_OF_MONTH, -7);
				paymentDate = computeDate(startDate, cycleTenorInt*3);
			}
	    }



		McfeCustomerRepaymentPlanDTO plan = initPlan(contract, principal, interest, date, tenor, fundInterest);
		// 利随本清只有一期
		plan.setTenor(1);
		plan.setPaymentDate(paymentDate);
		plan.setPaymentDateLate(paymentDate);
		list.add(plan);
		return list;
	}

	/**
	 * 初始化还款计划
	 *
	 * @param contract
	 *            合同信息
	 * @param monthlyPrincipal
	 *            月还款本金
	 * @param monthlyInterest
	 *            月还款利息
	 * @param date
	 *            贷款起始日期
	 * @param tenor
	 *            第tenor期
	 * @return
	 */
	public McfeCustomerRepaymentPlanDTO initPlan(McfeCustomerLoanContractDTO contract, BigDecimal monthlyPrincipal,
			BigDecimal monthlyInterest, Date date, int tenor, BigDecimal monthlyFundInterest) {
		McfeCustomerRepaymentPlanDTO plan = new McfeCustomerRepaymentPlanDTO();
		plan.setPlanCode(MarvelsUtils.generateUUIDCode("FE"));
		// 客户姓名
		plan.setCustName(contract.getCustName());
		// 客户证件
		plan.setCustCardNo(contract.getCustCardNo());
		// 渠道名称
		plan.setChannelName(contract.getChannelName());
		// 客户渠道
		plan.setChannelCode(contract.getChannelCode());
		// 状态
		plan.setStatus(MarvelsConstant.PAYMENT_PLAN_STATUS_NORMAL);
		// 期数
		plan.setTenor(tenor);
		// 金额 (本金+利息)
		// plan.setAmount(monthlyPrincipal.add(monthlyInterest));
		// 还款日期
		plan.setPaymentDate(computeDate(date, tenor));
		plan.setPaymentDateLate(computeDate(date, tenor));
		// 产品小类code
		plan.setProductCode(contract.getProductCode());
		// 产品小类名称
		plan.setProductName(contract.getProductName());
		// 产品大类
		plan.setProductType(contract.getProductType());
		// 产品大类名称
		plan.setProductTypeName(contract.getProductTypeName());
		// 本金
		plan.setPrincipal(monthlyPrincipal);
		// 利息
		plan.setInterest(monthlyInterest);
		// 资金源利息
		plan.setFundInterest(monthlyFundInterest);
		// 资金源本金
		plan.setFundPrincipal(monthlyPrincipal);
		// 创建人员
		plan.setCreatedBy(MarvelsConstant.SYSTEM_USER);
		// 创建时间
		plan.setCreatedDate(new Date());
		// 最后更新人员
		plan.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
		// 最后更新时间
		plan.setUpdatedDate(new Date());
		// 延滞天数
		plan.setDelqDays(0);
		// 渠道受理号
		plan.setLoanId(contract.getLoanId());

		plan.setFundCode(contract.getFundCode());

		plan.setFundName(contract.getFundName());
		return plan;
	}

	/**
	 * 根据firstDate往后顺延tenor月
	 *
	 * @param firstDate
	 * @param tenor
	 * @return
	 */
	private Date computeDate(Date firstDate, int tenor) {
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(firstDate);
		gc.add(GregorianCalendar.MONTH, tenor);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		return gc.getTime();
	}

	/**
	 * 按天计算还款日期
	 *
	 * @param firstDate
	 * @param tenor
	 * @return
	 */
	private Date computeDateForDay(Date firstDate, int tenor) {
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(firstDate);
		gc.add(GregorianCalendar.DAY_OF_MONTH, tenor);
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		return gc.getTime();
	}

	/**
	 * 根据各种费用及根据产品宽限期更新最后还款日等信息
	 *
	 * @author 娄凯琦
	 * @date 2018年5月10日
	 * @param amount
	 * @param list
	 * @param mcptPlatformFeeDTO
	 * @param mcptMiscFeeDTO
	 * @param mcptManagementFeeDTO
	 * @param mcptConsultingFeeDTO
	 * @param mcptProduct
	 * @param roundDigits
	 * @param roundUpFlag
	 * @return
	 */
	private List<McfeCustomerRepaymentPlanDTO> updateFeeForPlan(BigDecimal amount,
			List<McfeCustomerRepaymentPlanDTO> list, McptPlatformFeeDTO mcptPlatformFeeDTO,
			McptMiscFeeDTO mcptMiscFeeDTO, McptManagementFeeDTO mcptManagementFeeDTO,
			McptConsultingFeeDTO mcptConsultingFeeDTO, McptProduct mcptProduct, int roundDigits, int roundUpFlag) {

		// 管理费
		BigDecimal managementFee = BigDecimal.ZERO.setScale(2);
		// 咨询费
		BigDecimal consultingFee = BigDecimal.ZERO.setScale(2);
		// 平台费
		BigDecimal platformFee = BigDecimal.ZERO.setScale(2);
		// 杂费
		BigDecimal miscFee = BigDecimal.ZERO.setScale(2);
		// 最后还款日
		Date paymentDueDate;

		Iterator<McfeCustomerRepaymentPlanDTO> iterator = list.iterator();
		while (iterator.hasNext()) {

			McfeCustomerRepaymentPlanDTO plan = iterator.next();
			// 计算各个费用
			if(null != mcptPlatformFeeDTO) {
				platformFee = computePlatformFee(mcptPlatformFeeDTO, amount, plan.getTenor())
						.setScale(roundDigits, roundUpFlag);
			}
			if(null != mcptMiscFeeDTO) {
				miscFee = computeMiscFee(mcptMiscFeeDTO, amount, plan.getTenor()).setScale(roundDigits,
						roundUpFlag);
			}

			if(null != mcptManagementFeeDTO) {
				managementFee = computemManagementFee(mcptManagementFeeDTO, amount, plan.getTenor())
						.setScale(roundDigits, roundUpFlag);
			}

			if(null != mcptConsultingFeeDTO) {
				consultingFee = computeConsultingFee(mcptConsultingFeeDTO, amount, plan.getTenor())
						.setScale(roundDigits, roundUpFlag);
			}

			// 根据产品宽限期，计算最后还款日
			// paymentDueDate =
			// LoanUtil.computePerDayDate(plan.getPaymentDate(),
			// product.getGraceDays());
			// 更新还款计划
			// 管理费1
			plan.setManagementFee(managementFee);
			// 咨询费2
			plan.setConsultingFee(consultingFee);
			//收砍头息时直接将已收咨询费用咨询费填充
			plan.setConsultingFeeAct(consultingFee);
			// 平台费
			plan.setPlatformFee(platformFee);
			// 杂费
			plan.setMiscFee(miscFee);
			// 风险金
			// plan.setRiskFee(riskf);
			// 总费用
			// plan.setFee(plan.getServiceFee1().add(plan.getServiceFee2()).add(plan.getPlatformFee())
			// .add(plan.getMiscFee()).add(plan.getRiskFee()));
			// 最后还款日
			// plan.setPaymentDueDate(paymentDueDate);
			// 最后更新人员
			plan.setUpdatedBy(MarvelsConstant.SYSTEM_USER);
			// 最后更新时间
			plan.setUpdatedDate(new Date());
		}
		return list;
	}

	/**
	 * 计算平台费
	 *
	 * @param obj
	 * @param principal
	 * @return
	 */
	private BigDecimal computePlatformFee(McptPlatformFeeDTO mcptPlatformFeeDTO, BigDecimal principal, int tenor) {
		BigDecimal amount = BigDecimal.ZERO;
		if (principal.compareTo(BigDecimal.ZERO) == 0)
			return amount;
		// 获取费用收取方式
		String chargeMethod = mcptPlatformFeeDTO.getChargeMethod() + "";
		// 获取最小费用
		BigDecimal minFee = mcptPlatformFeeDTO.getMinFee();
		// 获取最大费用
		BigDecimal maxFee = mcptPlatformFeeDTO.getMaxFee();
		// 获取费用类型
		String feeType = mcptPlatformFeeDTO.getFeeType() + "";
		// 获取基础费用
		BigDecimal baseFee = mcptPlatformFeeDTO.getBaseFee();

		// 费用类型为固定金额
		if (MarvelsConstant.FEE_TYPE_FIXED.equalsIgnoreCase(feeType)) {
			amount = baseFee;
		}
		// 费用类型：百分比（变动）
		else if (MarvelsConstant.FEE_TYPE_VAR.equalsIgnoreCase(feeType)) {
			// 获取费用百分比
			BigDecimal percentage = mcptPlatformFeeDTO.getPercentage();
			// 计算金额
			amount = baseFee.add(principal.multiply(percentage));
		}
		// 费用类型：阶段
		else if (MarvelsConstant.FEE_TYPE_TIER.equalsIgnoreCase(feeType)) {
			// 获取阶段收取方式
			String tierFlag = mcptPlatformFeeDTO.getTierFlag() + "";
			// 获取各个阶段的阈值
			// 阶段1
			BigDecimal limit1 = BigDecimal.valueOf(mcptPlatformFeeDTO.getPhase1Limit());
			// 阶段2
			BigDecimal limit2 = BigDecimal.valueOf(mcptPlatformFeeDTO.getPhase2Limit());
			// 阶段方式：金额
			if (MarvelsConstant.FEE_TIER_AMOUNT.equalsIgnoreCase(tierFlag)) {
				// 获取各阶段金额
				BigDecimal amount1 = mcptPlatformFeeDTO.getPhase1Amount();
				BigDecimal amount2 = mcptPlatformFeeDTO.getPhase2Amount();
				BigDecimal amount3 = mcptPlatformFeeDTO.getPhase3Amount();
				// 大于阶段2阈值
				if (principal.compareTo(limit2) > 0) {
					amount = amount1.add(amount2).add(amount3);
				} else if (principal.compareTo(limit1) > 0) {
					amount = amount1.add(amount2);
				} else {
					amount = amount1;
				}
			}
			// 阶段方式：百分比
			else if (MarvelsConstant.FEE_TIER_PERCENTAGE.equalsIgnoreCase(tierFlag)) {
				// 获取3个阶段比例
				BigDecimal percen1 = mcptPlatformFeeDTO.getPhase1Percentage();
				BigDecimal percen2 = mcptPlatformFeeDTO.getPhase2Percentage();
				BigDecimal percen3 = mcptPlatformFeeDTO.getPhase3Percentage();
				// 先设三个阶段的费用
				// 3阶段需收费用
				BigDecimal amount3Act = BigDecimal.ZERO;
				// 2阶段需收费用
				BigDecimal amount2Act = BigDecimal.ZERO;
				// 1阶段需收费用
				BigDecimal amount1Act = BigDecimal.ZERO;
				if (principal.compareTo(limit2) > 0) {
					// 3阶段需收费用
					amount3Act = principal.subtract(limit2).multiply(percen3);
					// 2阶段需收费用
					amount2Act = limit2.subtract(limit1).multiply(percen2);
					// 1阶段需收费用
					amount1Act = limit1.multiply(percen1);
				} else if (principal.compareTo(limit1) > 0) {
					amount2Act = principal.subtract(limit1).multiply(percen2);
					amount1Act = limit1.multiply(percen1);
				} else {
					amount1Act = principal.multiply(percen1);
				}
				amount = amount1Act.add(amount2Act).add(amount3Act);
			}
			amount = amount.add(baseFee);
		}
//		MarvelsLogUtil.getInstance().info("amount:"+mcptPlatformFeeDTO.getBaseFee());
		// 与最小费用和最大费用比较
		if (amount.compareTo(minFee) < 0) {
			amount = minFee;
		}
		if (amount.compareTo(maxFee) > 0) {
			amount = maxFee;
		}
		// 根据费用收取方式及当前期数，生成最后的费用
		// 一次收取
		if (MarvelsConstant.CHARGE_METHOD_ONE_TIME_CHARGE.equalsIgnoreCase(chargeMethod)) {
			if (tenor != 1) {
				amount = BigDecimal.ZERO.setScale(2);
			}
		}
		return amount;
	}

	/**
	 * 计算杂费
	 *
	 * @param obj
	 * @param principal
	 * @return
	 */
	private BigDecimal computeMiscFee(McptMiscFeeDTO mcptMiscFeeDTO, BigDecimal principal, int tenor) {
		BigDecimal amount = BigDecimal.ZERO;
		if (principal.compareTo(BigDecimal.ZERO) == 0)
			return amount;
		// 获取费用收取方式
		String chargeMethod = mcptMiscFeeDTO.getChargeMethod() + "";
		// 获取最小费用
		BigDecimal minFee = mcptMiscFeeDTO.getMinFee();
		// 获取最大费用
		BigDecimal maxFee = mcptMiscFeeDTO.getMaxFee();
		// 获取费用类型
		String feeType = mcptMiscFeeDTO.getFeeType() + "";
		// 获取基础费用
		BigDecimal baseFee = mcptMiscFeeDTO.getBaseFee();
		// 费用类型为固定金额
		if (MarvelsConstant.FEE_TYPE_FIXED.equalsIgnoreCase(feeType)) {
			amount = baseFee;
		}
		// 费用类型：百分比（变动）
		else if (MarvelsConstant.FEE_TYPE_VAR.equalsIgnoreCase(feeType)) {
			// 获取费用百分比
			BigDecimal percentage = mcptMiscFeeDTO.getPercentage();
			// 计算金额
			amount = baseFee.add(principal.multiply(percentage));
		}
		// 费用类型：阶段
		else if (MarvelsConstant.FEE_TYPE_TIER.equalsIgnoreCase(feeType)) {
			// 获取阶段收取方式
			String tierFlag = mcptMiscFeeDTO.getTierFlag() + "";
			// 获取各个阶段的阈值
			// 阶段1
			BigDecimal limit1 = BigDecimal.valueOf(mcptMiscFeeDTO.getPhase1Limit());
			// 阶段2
			BigDecimal limit2 = BigDecimal.valueOf(mcptMiscFeeDTO.getPhase2Limit());
			// 阶段方式：金额
			if (MarvelsConstant.FEE_TIER_AMOUNT.equalsIgnoreCase(tierFlag)) {
				// 获取各阶段金额
				BigDecimal amount1 = mcptMiscFeeDTO.getPhase1Amount();
				BigDecimal amount2 = mcptMiscFeeDTO.getPhase2Amount();
				BigDecimal amount3 = mcptMiscFeeDTO.getPhase3Amount();
				// 大于阶段2阈值
				if (principal.compareTo(limit2) > 0) {
					amount = amount1.add(amount2).add(amount3);
				} else if (principal.compareTo(limit1) > 0) {
					amount = amount1.add(amount2);
				} else {
					amount = amount1;
				}
			}
			// 阶段方式：百分比
			else if (MarvelsConstant.FEE_TIER_PERCENTAGE.equalsIgnoreCase(tierFlag)) {
				// 获取3个阶段比例
				BigDecimal percen1 = mcptMiscFeeDTO.getPhase1Percentage();
				BigDecimal percen2 = mcptMiscFeeDTO.getPhase2Percentage();
				BigDecimal percen3 = mcptMiscFeeDTO.getPhase3Percentage();
				// 先设三个阶段的费用
				// 3阶段需收费用
				BigDecimal amount3Act = BigDecimal.ZERO;
				// 2阶段需收费用
				BigDecimal amount2Act = BigDecimal.ZERO;
				// 1阶段需收费用
				BigDecimal amount1Act = BigDecimal.ZERO;
				if (principal.compareTo(limit2) > 0) {
					// 3阶段需收费用
					amount3Act = principal.subtract(limit2).multiply(percen3);
					// 2阶段需收费用
					amount2Act = limit2.subtract(limit1).multiply(percen2);
					// 1阶段需收费用
					amount1Act = limit1.multiply(percen1);
				} else if (principal.compareTo(limit1) > 0) {
					amount2Act = principal.subtract(limit1).multiply(percen2);
					amount1Act = limit1.multiply(percen1);
				} else {
					amount1Act = principal.multiply(percen1);
				}
				amount = amount1Act.add(amount2Act).add(amount3Act);
			}
			amount = amount.add(baseFee);
		}
		// 与最小费用和最大费用比较
		if (amount.compareTo(minFee)<0) {
			amount = minFee;
		}
		if (amount.compareTo(maxFee) >0) {
			amount = maxFee;
		}
		// 根据费用收取方式及当前期数，生成最后的费用
		// 一次收取
		if (MarvelsConstant.CHARGE_METHOD_ONE_TIME_CHARGE.equalsIgnoreCase(chargeMethod)) {
			if (tenor != 1) {
				amount = BigDecimal.ZERO.setScale(2);
			}
		}
		return amount;
	}

	/**
	 * 计算管理费
	 *
	 * @param obj
	 * @param principal
	 * @return
	 */
	private BigDecimal computemManagementFee(McptManagementFeeDTO mcptManagementFeeDTO, BigDecimal principal, int tenor) {
		BigDecimal amount = BigDecimal.ZERO;
		if (principal.compareTo(BigDecimal.ZERO) == 0)
			return amount;
		// 获取费用收取方式
		String chargeMethod = mcptManagementFeeDTO.getChargeMethod() + "";
		// 获取最小费用
		BigDecimal minFee = mcptManagementFeeDTO.getMinFee();
		// 获取最大费用
		BigDecimal maxFee = mcptManagementFeeDTO.getMaxFee();
		// 获取费用类型
		String feeType = mcptManagementFeeDTO.getFeeType() + "";
		// 获取基础费用
		BigDecimal baseFee = mcptManagementFeeDTO.getBaseFee();
		// 费用类型为固定金额
		if (MarvelsConstant.FEE_TYPE_FIXED.equalsIgnoreCase(feeType)) {
			amount = baseFee;
		}
		// 费用类型：百分比（变动）
		else if (MarvelsConstant.FEE_TYPE_VAR.equalsIgnoreCase(feeType)) {
			// 获取费用百分比
			BigDecimal percentage = mcptManagementFeeDTO.getPercentage();
			// 计算金额
			amount = baseFee.add(principal.multiply(percentage));
		}
		// 费用类型：阶段
		else if (MarvelsConstant.FEE_TYPE_TIER.equalsIgnoreCase(feeType)) {
			// 获取阶段收取方式
			String tierFlag = mcptManagementFeeDTO.getTierFlag() + "";
			// 获取各个阶段的阈值
			// 阶段1
			BigDecimal limit1 = BigDecimal.valueOf(mcptManagementFeeDTO.getPhase1Limit());
			// 阶段2
			BigDecimal limit2 = BigDecimal.valueOf(mcptManagementFeeDTO.getPhase2Limit());
			// 阶段方式：金额
			if (MarvelsConstant.FEE_TIER_AMOUNT.equalsIgnoreCase(tierFlag)) {
				// 获取各阶段金额
				BigDecimal amount1 = mcptManagementFeeDTO.getPhase1Amount();
				BigDecimal amount2 = mcptManagementFeeDTO.getPhase2Amount();
				BigDecimal amount3 = mcptManagementFeeDTO.getPhase3Amount();
				// 大于阶段2阈值
				if (principal.compareTo(limit2) > 0) {
					amount = amount1.add(amount2).add(amount3);
				} else if (principal.compareTo(limit1) > 0) {
					amount = amount1.add(amount2);
				} else {
					amount = amount1;
				}
			}
			// 阶段方式：百分比
			else if (MarvelsConstant.FEE_TIER_PERCENTAGE.equalsIgnoreCase(tierFlag)) {
				// 获取3个阶段比例
				BigDecimal percen1 = mcptManagementFeeDTO.getPhase1Percentage();
				BigDecimal percen2 = mcptManagementFeeDTO.getPhase2Percentage();
				BigDecimal percen3 = mcptManagementFeeDTO.getPhase3Percentage();
				// 先设三个阶段的费用
				// 3阶段需收费用
				BigDecimal amount3Act = BigDecimal.ZERO;
				// 2阶段需收费用
				BigDecimal amount2Act = BigDecimal.ZERO;
				// 1阶段需收费用
				BigDecimal amount1Act = BigDecimal.ZERO;
				if (principal.compareTo(limit2) > 0) {
					// 3阶段需收费用
					amount3Act = principal.subtract(limit2).multiply(percen3);
					// 2阶段需收费用
					amount2Act = limit2.subtract(limit1).multiply(percen2);
					// 1阶段需收费用
					amount1Act = limit1.multiply(percen1);
				} else if (principal.compareTo(limit1) > 0) {
					amount2Act = principal.subtract(limit1).multiply(percen2);
					amount1Act = limit1.multiply(percen1);
				} else {
					amount1Act = principal.multiply(percen1);
				}
				amount = amount1Act.add(amount2Act).add(amount3Act);
			}
			amount = amount.add(baseFee);
		}
		// 与最小费用和最大费用比较
		if (amount.compareTo(minFee)<0) {
			amount = minFee;
		}
		if (amount.compareTo(maxFee) >0) {
			amount = maxFee;
		}
		// 根据费用收取方式及当前期数，生成最后的费用
		// 一次收取
		if (MarvelsConstant.CHARGE_METHOD_ONE_TIME_CHARGE.equalsIgnoreCase(chargeMethod)) {
			if (tenor != 1) {
				amount = BigDecimal.ZERO.setScale(2);
			}
		}
		return amount;
	}

	/**
	 * 计算咨询费
	 *
	 * @param obj
	 * @param principal
	 * @return
	 */
	private BigDecimal computeConsultingFee(McptConsultingFeeDTO mcptConsultingFeeDTO, BigDecimal principal, int tenor) {
		BigDecimal amount = BigDecimal.ZERO;
		if (principal.compareTo(BigDecimal.ZERO) == 0)
			return amount;
		// 获取费用收取方式
		String chargeMethod = mcptConsultingFeeDTO.getChargeMethod() + "";
		// 获取最小费用
		BigDecimal minFee = mcptConsultingFeeDTO.getMinFee();
		// 获取最大费用
		BigDecimal maxFee = mcptConsultingFeeDTO.getMaxFee();
		// 获取费用类型
		String feeType = mcptConsultingFeeDTO.getFeeType() + "";
		// 获取基础费用
		BigDecimal baseFee = mcptConsultingFeeDTO.getBaseFee();
		// 费用类型为固定金额
		if (MarvelsConstant.FEE_TYPE_FIXED.equalsIgnoreCase(feeType)) {
			amount = baseFee;
		}
		// 费用类型：百分比（变动）
		else if (MarvelsConstant.FEE_TYPE_VAR.equalsIgnoreCase(feeType)) {
			// 获取费用百分比
			BigDecimal percentage = mcptConsultingFeeDTO.getPercentage();
			// 计算金额
			amount = baseFee.add(principal.multiply(percentage));
		}
		// 费用类型：阶段
		else if (MarvelsConstant.FEE_TYPE_TIER.equalsIgnoreCase(feeType)) {
			// 获取阶段收取方式
			String tierFlag = mcptConsultingFeeDTO.getTierFlag() + "";
			// 获取各个阶段的阈值
			// 阶段1
			BigDecimal limit1 = BigDecimal.valueOf(mcptConsultingFeeDTO.getPhase1Limit());
			// 阶段2
			BigDecimal limit2 = BigDecimal.valueOf(mcptConsultingFeeDTO.getPhase2Limit());
			// 阶段方式：金额
			if (MarvelsConstant.FEE_TIER_AMOUNT.equalsIgnoreCase(tierFlag)) {
				// 获取各阶段金额
				BigDecimal amount1 = mcptConsultingFeeDTO.getPhase1Amount();
				BigDecimal amount2 = mcptConsultingFeeDTO.getPhase2Amount();
				BigDecimal amount3 = mcptConsultingFeeDTO.getPhase3Amount();
				// 大于阶段2阈值
				if (principal.compareTo(limit2) > 0) {
					amount = amount1.add(amount2).add(amount3);
				} else if (principal.compareTo(limit1) > 0) {
					amount = amount1.add(amount2);
				} else {
					amount = amount1;
				}
			}
			// 阶段方式：百分比
			else if (MarvelsConstant.FEE_TIER_PERCENTAGE.equalsIgnoreCase(tierFlag)) {
				// 获取3个阶段比例
				BigDecimal percen1 = mcptConsultingFeeDTO.getPhase1Percentage();
				BigDecimal percen2 = mcptConsultingFeeDTO.getPhase2Percentage();
				BigDecimal percen3 = mcptConsultingFeeDTO.getPhase3Percentage();
				// 先设三个阶段的费用
				// 3阶段需收费用
				BigDecimal amount3Act = BigDecimal.ZERO;
				// 2阶段需收费用
				BigDecimal amount2Act = BigDecimal.ZERO;
				// 1阶段需收费用
				BigDecimal amount1Act = BigDecimal.ZERO;
				if (principal.compareTo(limit2) > 0) {
					// 3阶段需收费用
					amount3Act = principal.subtract(limit2).multiply(percen3);
					// 2阶段需收费用
					amount2Act = limit2.subtract(limit1).multiply(percen2);
					// 1阶段需收费用
					amount1Act = limit1.multiply(percen1);
				} else if (principal.compareTo(limit1) > 0) {
					amount2Act = principal.subtract(limit1).multiply(percen2);
					amount1Act = limit1.multiply(percen1);
				} else {
					amount1Act = principal.multiply(percen1);
				}
				amount = amount1Act.add(amount2Act).add(amount3Act);
			}
			amount = amount.add(baseFee);
		}
		// 与最小费用和最大费用比较
		if (amount.compareTo(minFee) <0) {
			amount = minFee;
		}
		if (amount.compareTo(maxFee)>0) {
			amount = maxFee;
		}
		// 根据费用收取方式及当前期数，生成最后的费用
		// 一次收取
		if (MarvelsConstant.CHARGE_METHOD_ONE_TIME_CHARGE.equalsIgnoreCase(chargeMethod)) {
			if (tenor != 1) {
				amount = BigDecimal.ZERO.setScale(2);
			}
		}
		return amount;
	}

	/**
	 * 通过反射机制获取某一属性值
	 *
	 * @param obj
	 * @param name
	 * @return
	 */
	private Object getValue(Object obj, String name) {
		Class clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		try {
			for (Field field : fields) {
				if (name.equals(field.getName())) {
					PropertyDescriptor pd = new PropertyDescriptor(name, clazz);
					Method method = pd.getReadMethod();
					return method.invoke(obj);
				}
			}
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().error(">>>>>>通过反射机制获取某一属性值异常:",e);
		}
		return null;
	}

	@Override
	public Object withholdingTrial(Object obj) throws MarvelsBusinessException {

		return null;
	}

}
